using System.Collections.Generic;
using CfgTable;
using IQIGame.Onigao.GamePlay;
using NetProtocol.Enum;
using NetProtocol.POD;

namespace IQIGame.Onigao.Logic
{
    public class LogicQuestData
    {
        /// <summary>
        /// 任务唯一id
        /// </summary>
        public long id { get; private set; }
        /// <summary>
        /// 任务配置
        /// </summary>
        public CfgQuest cfg { get; private set; }
        public int cid => cfg.Id;

        /// <summary>
        /// 任务进度
        /// </summary>
        public int progress { get; set; }

        /// <summary>
        /// 创建时间(毫秒)
        /// </summary>
        public long createTime { get; set; }

        /// <summary>
        /// 父任务id
        /// </summary>
        public int parentCid { get; set; }
        /// <summary>
        /// 任务状态
        /// </summary>
        public QuestStatus status { get; set; }

        /// <summary>
        /// 子任务状态信息
        /// </summary>
        public Dictionary<int, int> childStatusMap { get; }
        /// <summary>
        /// 领奖阶段
        /// </summary>
        public int rewardPhase;

        public LogicQuestData(long id, CfgQuest cfg)
        {
            this.id = id;
            this.cfg = cfg;
            this.childStatusMap = new Dictionary<int, int>(cfg.ChildQuests.Count);
        }

        public static LogicQuestData CreateFromPOD(QuestPOD questPod)
        {
            var cfg = TableCenter.quest.Get(questPod.cid);
            if (cfg == null)
            {
                return null;
            }
            var questData = new LogicQuestData(questPod.id, cfg);
            questData.SyncData(questPod);
            return questData;
        }

        /// <summary>
        /// 是否有父任务
        /// </summary>
        public bool hasParent => parentCid > 0;

        #region status

        /// <summary>
        /// 进度值是否已达成 -- 进度值可逆
        /// </summary>
        public bool isProgressMet => progress >= cfg.TargetNum;

        /** 任务是否已进入完成状态 */
        public bool isCompleted => status >= QuestStatus.Accepted;

        /** 任务是否已进入失败状态 -- 失败状态不可逆 */
        public bool isFailed => status == QuestStatus.Failed;

        /** 任务是否已进入成功完成状态 -- 完成状态不可逆 */
        public bool isFinished => status == QuestStatus.Finished;

        /** 任务是否已进入提交状态 -- 提交状态不可逆 */
        public bool isCommitted => status == QuestStatus.Committed;

        /// <summary>
        /// 是否处于活跃状态
        /// </summary>
        /// <param name="curTime"></param>
        /// <returns></returns>
        public bool IsActive(long curTime)
        {
            return status == QuestStatus.Accepted && isOpening(curTime);
        }

        /// <summary>
        /// 是否处于开放状态 -- 在有效时间段内
        /// </summary>
        /// <param name="curTime"></param>
        /// <returns></returns>
        public bool isOpening(long curTime)
        {
            return true;
        }

        #endregion

        #region sync-data

        public void SyncData(QuestPOD questPod)
        {
            this.progress = questPod.progress;
            this.createTime = questPod.createTime;
            this.status = questPod.status;

            this.parentCid = questPod.parentCid;
            this.childStatusMap.Clear();
            this.childStatusMap.AddRange(questPod.childStatusMap);
            this.rewardPhase = questPod.rewardPhase;
        }

        public static LogicQuestData Create(CfgQuest cfg)
        {
            long id = LogicHelper.AllocGUID.Invoke();
            LogicQuestData questData = new LogicQuestData(id, cfg);
            questData.progress = cfg.InitNum;
            questData.createTime = LogicHelper.TimeNow;
            return questData;
        }

        public QuestPOD ToPOD()
        {
            QuestPOD questPod = new QuestPOD()
            {
                id = id,
                cid = cid,
                progress = progress,
                createTime = createTime,
                status = status,
                parentCid = parentCid,
                rewardPhase = rewardPhase
            };
            questPod.childStatusMap.AddRange(childStatusMap);
            return questPod;
        }

        #endregion

        #region util

        /** 获取已提交的子任务数量 -- 前提是保存了成功完成的子任务 */
        public int CountCommittedChild()
        {
            int r = 0;
            foreach (KeyValuePair<int, int> pair in childStatusMap)
            {
                if (pair.Value == (int)QuestStatus.Committed)
                {
                    r++;
                }
            }
            return r;
        }

        /** 获取已失败的子任务数量 -- 前提是保存了失败的子任务 */
        public int CountFailedChild()
        {
            int r = 0;
            foreach (KeyValuePair<int, int> pair in childStatusMap)
            {
                if (pair.Value == (int)QuestStatus.Failed)
                {
                    r++;
                }
            }
            return r;
        }

        /** 获取顺序完成的子任务数量 */
        public int CountSequencedCommittedChild()
        {
            int r = 0;
            for (int i = 0; i < cfg.ChildQuests.Count; i++)
            {
                int childQuestCid = cfg.ChildQuests[i];
                if (!childStatusMap.TryGetValue(childQuestCid, out int childStatus)
                    || childStatus != (int)QuestStatus.Committed)
                {
                    break;
                }
                r++;
            }
            return r;
        }

        #endregion
    }
}